<?php
/**
 * 创客报单数据入库类
 * @author liujun
 */
namespace App\System\Cis\Services;

use App\Jobs\SendMsg;
use App\System\Cis\Repositories\CisUserRepository;
use App\System\Coupon\Repositories\CouponUserRepository;
use App\System\Fina\Repositories\FinaIntegralRegRecordRepository;
use App\System\Log\Repositories\LogDeclarationFormRepository;
use App\System\Log\Repositories\LogSmsRepository;
use Illuminate\Support\Facades\DB;

class DeclarationStorageService
{
    /**
     * 输入的数据集合
     * @obj
     */
     public $inputDataObj;

    /**
     * 错误信息
     * @var
     */
    private $errorMsg;

    /**
     * 用户模型对像
     * @var
     */
    private $userObj;

    /**
     * 短信记录模型对像
     * @var
     */
    private $logSms;

    /**
     * 主帐号ID
     * @var
     */
    private $masterUserId;

    /**
     * 所有用上级用户数据
     * @var
     */
    private $superiorUserData;

    /**
     * 当次生成的用户ID数组
     * @var
     */
    private $userIds=[];

    /**
     * 城市合伙人报单财务记录ID数组
     * @var array
     */
    private $financialIds = [];

    /**
     * 节点区域 1创业区 2创新区 3创客区
     * @var
     */
    private $nodeRegion;

    /**
     * @var
     * 要发送的短信数组
     */
    private $smsData;

    /**
     * 城市合伙人报单每单价格
     */
    const UNIT_PRICE = 1000;

    /**
     * 生产环境顶级用户ID
     */
    const PRODUCTION_USER_ID = 2;

    /**
     * 开发环境顶级用户ID
     */
    const DEVELOP_USER_ID = 3;

    /**
     * 第三方公司环境顶级用户ID
     */
    const PRODUCTION_B_USER_ID = 4;


    public function __construct(DeclarationInputValidationService $inputData)
    {
        $this->inputDataObj = $inputData;
        $this->userObj = CisUserRepository::getInstance();
        $this->logSms = LogSmsRepository::getInstance();


    }

    /**
     * 生成用户总入口
     */
    public function getDeclarationResult()
    {
        DB::beginTransaction();
        $this->generateFinancialRecord();//扣奖城市合伙人财务并生成记录
        if($this->errorMsg) return $this->errorMsg;
        $this->generateMasterUser();//生成一个主创客帐号
        if($this->errorMsg) return $this->errorMsg;
        $this->generateUser();//生成创客
        if($this->errorMsg) return $this->errorMsg;
        $this->generateEntryRecord();//生成报单记录
        if($this->errorMsg) return $this->errorMsg;
        DB::commit();
        //$this->sendMsg();//执行发送短信推送到队列
    }

    /**
     * 生成主创客
     */
    private function generateMasterUser()
    {
        if(!$this->inputDataObj->getPersonalAccount())
        {//主帐号不存在创建一个
            $user = ['mobile'=>$this->inputDataObj->accountOwnerMobile,'password'=>bcrypt($this->inputDataObj->accountOwnerMobile)];
            $parent_id = $this->userObj->CreateUser($user);
            if(!$parent_id)
            {
                return $this->errorMsg = '生成主帐号失败';
            }
        }
        else
        {
            $parent_id = $this->inputDataObj->getPersonalAccount()->id;//主帐号ID
        }
        $this->masterUserId = $parent_id;
        return $this->masterUserId;
    }

    /**
     * 查找滑落的节点
     */
    private function queryNode()
    {
        $current_layer_id = $this->inputDataObj->recommendId;//定位到当前层
        $node = $this->userObj->queryNodeUser(null,$current_layer_id,1);//先查创业区有没有人
        $superior_maker_id = $current_layer_id;
        if($node)
        {//创业区存在
            $user_area = $this->inputDataObj->market;
            $i=1;
            while ($i)
            {//循环往下层查找
                $node = $this->userObj->queryNodeUser(null,$superior_maker_id,$user_area);
                if($node)
                {
                    $superior_maker_id = $node->id;
                    if($i==1)
                    {
                        $user_area = 1;
                        $this->nodeRegion = 1;
                    }
                    $i++;
                }
                else
                {//创新区不存在,改创新区
                    if($i==1)
                    {
                        $this->nodeRegion = $this->inputDataObj->market;
                    }
                    $i=0;
                }
            }
        }
        else
        {//创业区不存在，先放创业区
            $this->nodeRegion = 1;
        }

        return $superior_maker_id;
    }

    /**
     * 生成子创客
     */
    private function generateUser()
    {
        $current_layer_id = $this->queryNode();
        $superior_maker_ids = $this->userObj->getUser($current_layer_id);
        $superior_maker_ids = $superior_maker_ids->superior_maker_ids.','.$current_layer_id;
        $set = [
                'parent_id'=>$this->masterUserId,
                'mobile'=>$this->inputDataObj->accountOwnerMobile,
                'user_area'=>$this->nodeRegion,
                'user_type'=>1,
                'referee_id' => $this->inputDataObj->recommendId,
                'city_partner_id' => $this->inputDataObj->cityPartnerId,
                'superior_maker_id' =>$current_layer_id,
                'superior_maker_ids' => $superior_maker_ids,
                ];
        $seven_user_id = 0;
        $temp_front_superior_maker_ids = '';
        for ($i=0;$i<$this->inputDataObj->generatingNumber;$i++)
        {//循环生成用户
            $front_superior_maker_ids = $set['superior_maker_ids'];//保存一份生成前的上级ID
            $user_id = $this->userObj->CreateUser($set);

            if($i==0)
            {
                $seven_user_id = $user_id;//用于13个生成规则，保存第个生成用户的ID
            }
            if(!$user_id)
            {
                return $this->errorMsg = '创客生成失败';
                break;
            }
            else
            {//生成成功执行相关的业务操作

                $this->userIds[] = $user_id;
                $set['superior_maker_id'] = $user_id;
                $set['user_area'] = 1;
                $set['superior_maker_ids'] = $set['superior_maker_ids'].','.$user_id;//下级ID把自己也拼接进去
                $this->generateCoupon($user_id);
                if($this->errorMsg) return $this->errorMsg;
                $this->performanceRebate($set['superior_maker_ids']);
                if($i==5)
                {
                    $temp_front_superior_maker_ids = $set['superior_maker_ids'];
                }
                if($i==6)
                {//13个创客生成规则，生成到第7个创客时自动切换区域,上级也要切换到第七个生成的用户上
                    $set['user_area'] = 2;
                    $set['superior_maker_id'] = $seven_user_id;
                    $set['superior_maker_ids'] = $superior_maker_ids.','.$seven_user_id;
                    $front_superior_maker_ids = $temp_front_superior_maker_ids;
                }
                if($this->errorMsg) return $this->errorMsg;
                $this->updateStatisticalData($front_superior_maker_ids);
                if($this->errorMsg) return $this->errorMsg;
                $this->serviceAward($user_id);
                if($this->errorMsg) return $this->errorMsg;
            }
        }
        $this->generateMessageRecord($set['mobile'],11,0,[implode(',',$this->userIds)]);
    }

    /**
     * 生成购物券
     * @param $user_id 用户ID
     * @return integer
     */
    private function generateCoupon($user_id)
    {
        $couponUser = CouponUserRepository::getInstance();
        $set = ['amount'=>self::UNIT_PRICE,
                'expire_time'=>date("Y-m-d H:i:s",strtotime("+30 day")),
                'user_id'=>$user_id,
                'status'=>0
                ];
        $id = $couponUser->createCoupon($set);
        if(!$id)
        {
            return $this->errorMsg = '购物券生成失败';
        }
        return $id;
    }
      /**
     * 16层管理奖返利
     * @param $user_ids 创客用户数组
     * @return boolean
     */
    private function performanceRebate($user_ids)
    {
        if($user_ids)
        {
            $finaObj = FinaIntegralRegRecordRepository::getInstance();
            $user_ids = explode(",",$user_ids);
            rsort($user_ids);//倒序
            $layer = count($user_ids);//统计数组用户数
            $user = $this->userObj->getByInUser($user_ids);
            $this->superiorUserData = $user;//赋值所有上级用户数据，后续业务更新用户业绩用
            if($layer>16)
            {//上层人数超出16层要进行删除
                $num =1;
                $user_ids_array = [];
                foreach ($user_ids as $v)
                {
                    if($num>16)
                    {//超出16退出循环
                        break;
                    }
                    $user_ids_array[]=$v;
                    $num ++;
                }
                $user_ids = $user_ids_array;
            }
            $user_info_array = [];
            foreach ($user as $v)
            {
                $user_info_array[$v->id][1] = $v->integral;
                $user_info_array[$v->id][2] = $v->registered_currency;
                $user_info_array[$v->id]['status'] = $v->status;
                $user_info_array[$v->id]['repeated_consumption_date'] = $v->repeated_consumption_date;
                $user_info_array[$v->id]['user_renew'] = $v->user_renew;
            }
            $total_cash = self::UNIT_PRICE * 0.005;//获取到的总金额
            $commission = ($total_cash * 0.1)/2;//积分注册各自手续费
            $cash = $total_cash/2-$commission;//积分注册币各收入
            $set = [
                    'income'=>1,
                    'type'=>8,
                    'cash'=>$cash,
                    'commission'=>$commission,
                    'status'=>1
                    ];
            for ($i=1;$i<3;$i++)
            {//1积分，2注册币
                foreach ($user_ids as $v)
                {
                    if(!$v) continue;
                    if($user_info_array[$v]['status'] !=1 || !$user_info_array[$v]['repeated_consumption_date'] || $user_info_array[$v]['repeated_consumption_date'] < date("Y-m-d") || $user_info_array[$v]['user_renew'] !=1 )
                    {
                        continue;//用户状态异常，或没有满足发功资条件，或没有复销的奖励不发放，
                    }
                    $set['record_type'] = $i;
                    $set['after_cash'] = $user_info_array[$v][$i] + $cash;
                    $set['user_id'] = $v;
                    $fina_id = $finaObj->createFina($set);//生成管理奖财务记录
                    if(!$fina_id)
                    {
                        return $this->errorMsg = '管理奖记录生成错误';
                    }
                    else
                    {
                        $column_array = [1=>'integral',2=>'registered_currency'];
                        $update_user = $this->userObj->updateUserPurse($v,1,$column_array[$i],$cash);
                        if(!$update_user) return $this->errorMsg = '用户钱包更新出错';
                    }
                    $this->generateMessageRecord(0,7,$v,[$cash,$cash]);//生成短信内容
                }
            }

        }
        return false;
    }

    /**
     * 更新上层用户数量,业绩
     * @param $user_ids 上层用户ID数组
     * @param $income 1增加 2减少
     * @return boolean
     */
    private function updateStatisticalData($user_ids,$income=1)
    {

        $user_market = [];
        foreach ($this->superiorUserData as $v)
        {
            //用当前用户的上级ID做KEY，当前用户的区域赋值，用于在后面进行业绩的更新
            if($v->superior_maker_id)
            {
                $user_market[$v->superior_maker_id] = $v->user_area;
            }
        }
        $achievement_array = [
                                1=>'entrepreneurship_achievement',
                                2=>'chuangheng_achievement',
                                3=>'director_achievement'
                             ];
        //1更新上层用户数量,业绩
        $user_ids = explode(",",$user_ids);
        foreach ($user_ids as $v)
        {
            if($v > 1)
            {
                $update = $this->userObj->updateUserManyPurse($v,$income,['total_users_number'=>1,$achievement_array[$user_market[$v]]=>self::UNIT_PRICE]);
                if(!$update)
                {
                    return $this->errorMsg = '更新用户数量，业绩出错';
                }
            }

        }

    }

    /**
     * 生成短信记录
     * @param $mobile 手机
     * @param $type 短信模板类型
     * @param array $user_id 用户ID
     * @param array $data 数据
     */
    private function generateMessageRecord($mobile,$type,$user_id=[],$data=[])
    {
        $this->smsData[] = ['mobile'=>$mobile,'type'=>$type,'user_id'=>$user_id,'data'=>$data];
    }

    /**
     * 发送短信
     */
    private function sendMsg()
    {
        if($this->smsData)
        {
            foreach ($this->smsData as $v)
            {
                SendMsg::dispatch($v['mobile'],$v['type'],$v['data'],$v['user_id']);
            }

        }
    }

    /**
     * 城市合伙人服务奖励
     * @param $user_id 生成的创客
     * @return string
     */
    private function serviceAward($user_id)
    {
        $total_cash = self::UNIT_PRICE * 0.04;//获取到的总金额
        $commission = ($total_cash * 0.1)/2;//积分注册各自手续费
        $cash = $total_cash/2-$commission;//积分注册币各收入
        $set = [
            'income'=>1,
            'type'=>12,
            'cash'=>$cash,
            'commission'=>$commission,
            'status'=>1,

        ];
        $city_partners_info = $this->userObj->getUser($this->inputDataObj->cityPartnerId);
        if($city_partners_info->user_renew !=1 || $city_partners_info->repeated_consumption_date < date("Y-m-d"))
        {
            return false;
        }
        $finaObj = FinaIntegralRegRecordRepository::getInstance();
        for($i=1;$i<3;$i++){
            $set['record_type'] = $i;
            if($i ==1)
            {
                $original_cash = $city_partners_info->integral;
            }else{
                $original_cash = $city_partners_info->registered_currency;
            }
            $set['after_cash'] = $original_cash + $cash;
            $set['user_id'] = $city_partners_info->id;
            $fina_id = $finaObj->createFina($set,$user_id);//生成服务奖励财务记录
            if(!$fina_id)
            {
                return $this->errorMsg = '服务奖励生成失败';
            }
        }
        $update = $this->userObj->updateUserManyPurse($city_partners_info->id,1,['integral'=>$cash,'registered_currency'=>$cash]);
        if(!$update)
        {
            return $this->errorMsg = '城市合伙人金额数据更新失败';
        }
        if($city_partners_info->mobile)
        {
            $this->generateMessageRecord($city_partners_info->mobile,8,0,[$cash,$cash]);
        }

    }

    /**
     * 生成报单财务记录并扣款
     * @return string
     */
    private function generateFinancialRecord()
    {
        $total_cash = self::UNIT_PRICE * $this->inputDataObj->generatingNumber;//报单需要的总额
        $average_amount = $total_cash/2;//注册币积分各一半
        $integral = $average_amount;
        $user_info = $this->inputDataObj->getPartnerInformation();//城市合伙人信息
        $registered_currency = $user_info->registered_currency;
        if($registered_currency < $average_amount)
        {//钱包注册币比当前消耗的小就用钱包的
            $integral = $average_amount + $average_amount-$registered_currency;//积分加上注册币不够扣的
        }
        else
        {//钱包大说当前就用当前的
            $registered_currency = $average_amount;
        }
        $finaObj = FinaIntegralRegRecordRepository::getInstance();
        $set = [
            'income'=>2,
            'type'=>5,
            'cash'=>$integral,
            'status'=>1,
            'commission'=>0,
            'record_type' =>1,
            'after_cash' =>$user_info->integral - $integral,
            'user_id' => $user_info->id
        ];
        $cash = [1=>$integral,2=>$registered_currency];
        for($i=1;$i<3;$i++){
            $set['cash'] = $i ==1 ? $integral : $registered_currency;
            $set['record_type'] = $i;
            $currency = $i == 1 ? 'integral' : 'registered_currency';
            $set['after_cash'] = $user_info->$currency - $cash[$i];
            $set['user_id'] = $user_info->id;
            $fina_id = $finaObj->createFina($set);//生成报单财务记录
            if(!$fina_id)
            {
                return $this->errorMsg = '报单财务生成失败';
            }
            $this->financialIds[]= $fina_id;
        }

        $update = $this->userObj->updateUserManyPurse($user_info->id,2,['integral'=>$integral,'registered_currency'=>$registered_currency]);
        if(!$update)
        {
            return $this->errorMsg = '城市合伙人金额数据更新失败';
        }
    }

    /**
     * 生成报单记录
     * @return string
     */
    private function generateEntryRecord(){
        //生成报单记录
        $log = LogDeclarationFormRepository::getInstance();
        $set = [
            'user_area'=>$this->inputDataObj->market,
            'number'=>$this->inputDataObj->generatingNumber,
            'recommender_id' => $this->inputDataObj->recommendId,
            'user_id' => $this->inputDataObj->cityPartnerId,
            'fina_ids' => implode(',',$this->financialIds),
            'generated_user_ids' => implode(',',$this->userIds)
        ];
        $insert = $log->CreateLog($set);
        if(!$insert)
        {
            return $this->errorMsg = '报单记录生成失败';
        }
    }

    /**
     * 获取错误信息
     * @return mixed
     */
    public function getErrorMsg()
    {
        return $this->errorMsg;
    }

    /**
     * 外部调用更新所有上级用户业绩入口
     * @param $user_ids array 当前用户所有上级用户ID数组
     * @param $user_id 当前用户ID
     * @param $income 1增加 2减少
     * @return string
     */
    public function externalUpdatePerformanceInterface($user_ids,$user_id,$income)
    {
        $user_ids_array  = explode(",",$user_ids);
        $user_ids_array[] = $user_id;
        $user = $this->userObj->getByInUser($user_ids_array);//查询所有上级用户包括自己的
        $this->superiorUserData = $user;
        $this->updateStatisticalData($user_ids,$income);
        return $this->errorMsg;
    }

    /**
     * 或取当次报单生成的所有用户
     */
    public function getUserIds()
    {
        return $this->userIds;
    }
}